﻿using SD.Infrastructure.Repository.EntityFrameworkCore;
using SlamDunk.MES.Domain.Entities.ExecutionContext;
using SlamDunk.MES.Domain.Entities.ResourceContext;
using SlamDunk.MES.Domain.IRepositories.Interfaces.ExecutionContext;
using SlamDunk.MES.ReportView.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SlamDunk.MES.Repository.Implements.ExecutionContext
{
    /// <summary>
    /// 工单实际设备仓储实现
    /// </summary>
    public class WorkOrderActualEquipmentRepository : EFEntityRepositoryProvider<WorkOrderActualEquipment>, IWorkOrderActualEquipmentRepository
    {
        #region # 获取工单实际设备列表 —— ICollection<WorkOrderActualEquipment> Find(Guid workOrderId)
        /// <summary>
        /// 获取工单实际设备列表
        /// </summary>
        /// <param name="workOrderId">工单Id</param>
        /// <returns>工单实际设备列表</returns>
        public ICollection<WorkOrderActualEquipment> Find(Guid workOrderId)
        {
            IQueryable<WorkOrderActualEquipment> actualEquipments = base.Find(x => x.WorkOrder.Id == workOrderId);

            return actualEquipments.ToList();
        }
        #endregion

        #region # 获取作业计划设备概要列表 —— ICollection<EquipmentSummaryInfo> GetEquipmentSummariesByExecutionPlan(...
        /// <summary>
        /// 获取作业计划设备概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <returns>设备概要列表</returns>
        public ICollection<EquipmentSummaryInfo> GetEquipmentSummariesByExecutionPlan(Guid executionPlanId)
        {
            IQueryable<WorkOrderActualEquipment> actualEquipmentsQueryable = base.Find(x => x.WorkOrder.ExecutionPlanId == executionPlanId);
            IQueryable<Guid> equipmentIds = actualEquipmentsQueryable.Select(x => x.EquipmentId).Distinct();

            IList<WorkOrderActualEquipment> actualEquipments = actualEquipmentsQueryable.ToList();
            IList<Equipment> equipments = this._dbContext.Set<Equipment>().Where(x => equipmentIds.Contains(x.Id)).ToList();

            IEnumerable<EquipmentSummaryInfo> equipmentSummaries =
                from actualEquipment in actualEquipments
                let equipment = equipments.Single(x => x.Id == actualEquipment.EquipmentId)
                let duration = actualEquipment.ActualEndTime - actualEquipment.ActualStartTime
                select new EquipmentSummaryInfo
                {
                    EquipmentId = equipment.Id,
                    EquipmentNo = equipment.Number,
                    EquipmentName = equipment.Name,
                    Machinehour = Convert.ToDecimal(duration.TotalHours)
                };

            var equipmentSummaryGroups = equipmentSummaries.GroupBy(x => new
            {
                x.EquipmentId,
                x.EquipmentNo,
                x.EquipmentName
            }).Select(x => new
            {
                x.Key,
                Machinehour = x.Any() ? x.Sum(y => y.Machinehour) : 0m
            });
            IEnumerable<EquipmentSummaryInfo> result =
                from equipmentSummaryGroup in equipmentSummaryGroups
                let machinehour = equipmentSummaryGroup.Machinehour
                select new EquipmentSummaryInfo
                {
                    EquipmentId = equipmentSummaryGroup.Key.EquipmentId,
                    EquipmentNo = equipmentSummaryGroup.Key.EquipmentNo,
                    EquipmentName = equipmentSummaryGroup.Key.EquipmentName,
                    Machinehour = machinehour
                };

            return result.ToList();
        }
        #endregion
    }
}
